home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c-part1 / 8489 < prev    next >
Encoding:
Text File  |  1996-08-05  |  2.2 KB  |  78 lines

  1. Path: keats.ugrad.cs.ubc.ca!not-for-mail
  2. From: c2a192@ugrad.cs.ubc.ca (Kazimir Kylheku)
  3. Newsgroups: comp.lang.c
  4. Subject: Re: Combine zero-offset with unit-offset arrays ?
  5. Date: 4 Mar 1996 09:57:25 -0800
  6. Organization: Computer Science, University of B.C., Vancouver, B.C., Canada
  7. Message-ID: <4hfau5INNme5@keats.ugrad.cs.ubc.ca>
  8. References: <4hes0h$52qi@info4.rus.uni-stuttgart.de>
  9. NNTP-Posting-Host: keats.ugrad.cs.ubc.ca
  10.  
  11. In article <4hes0h$52qi@info4.rus.uni-stuttgart.de>,
  12. Markus Heller  <Markus.Heller@studbox.uni-stuttgart.de> wrote:
  13. >Hi,
  14. >
  15. >I want to combine my code (using zero-offset arrays) with
  16. >code using unit-offset arrays.
  17. >The FAQ - 2.16 mentions a method used "in old editions of
  18. >Numerical Recipes in C" that leads to undefined behavior.
  19. >Unfortunately there's no alternative mentioned.
  20. >E.g.:
  21. >
  22. >void somefunction( float fa[], int n);
  23. >
  24. >int main(void)
  25. >{
  26. > float a[10];  /* zero offset: a[0] .. a[9] */
  27. > int n=10;
  28. >
  29. > somefunction( a-1, 10 ); /* method suggested by Numerical Recipes,
  30. >                             2nd edition */
  31. >}                               
  32. >void somefunction( float fa[], int n)
  33. >{
  34. > /* do something with a, assuming unit-offset: a[1]..a[10] */
  35. >}
  36. >
  37. >
  38. >Which alternatives are possible to the above mentioned method ?
  39.  
  40. Try this:
  41.  
  42. void somefunction(float fa[], int n)
  43. #define fa (fa-1)
  44. {
  45.     int foo = fa[1];
  46. }
  47.  
  48. int main(void)
  49. {
  50.     float a[10];
  51.  
  52.     somefunction(a,sizeof(a));
  53. }
  54.  
  55. >(Is the method still leasding to undefined behavior ?)
  56.  
  57. The expression fa[1] undergoes pre-processing, and becomes (fa-1)[1].
  58.  
  59. Of course, this is just equivalent to *((fa-1) + 1).  This is still undefined,
  60. though it's syntactically convenient. What you want is to add the 1 first, then
  61. subtract, in other words: *((fa+1) - 1). For this, you must break with the nice
  62. syntax and go for this:
  63.  
  64. #define fa(x) (fa[x-1])
  65. {
  66.     int foo = fa(1);
  67. }
  68.  
  69. which now gives you fa[1-1], which is *((fa) + 1 - 1). This is defined. The
  70. standard allows you generate a pointer which references one element past the
  71. end of the array, thus if you put in the subscript 10,  you would have
  72. *((fa) + 10 - 1). ANSI condones the generation of a pointer to the non-existant
  73. element of the array that is conceptually one index past the last one, in
  74. order to support certain common coding idioms.
  75. -- 
  76.  
  77.